package com.snlab;

import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Scanner;

import jdd.bdd.BDDIO;


public class App 
{
    public static void main( String[] args ) throws IOException
    {
        BDDEngine gEngine = new BDDEngine();
        String[] devicenames = {"atla", "chic", "hous", "kans", "losa", "newy32aoa", "salt", "seat"};
        for (String name : devicenames) {
            Device device = new Device(name, gEngine);
            try {
                Scanner in = new Scanner(new File("i2/" + name + "ap"));
                while (in.hasNextLine()) {
                    String line = in.nextLine();
                    String[] tokens = line.split(" ");
                    String pn = tokens[3].split("\\.")[0];
                    if (device.getPort(pn) == null) {
                        device.addPort(pn);
                    }
                    long ip = Long.parseLong(tokens[1]);
                    Rule rule = new Rule(device, ip, Integer.parseInt(tokens[2]), device.getPort(pn));
                    rule.setHit(device.bddEngine.encodeIpv4(BigInteger.valueOf(ip), Integer.parseInt(tokens[2])));
                    HashSet<Change> changes = device.identifyChangesInsert(rule);
                    for (Change change : changes) {
                        int hit = change.getHit();
                        ByteArrayOutputStream bos = new ByteArrayOutputStream();
                        try {
                            BDDIO.save(device.bddEngine.bdd, hit, bos);
                            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
                            BDDIO.load(gEngine.bdd, bis);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

        ArrayList<Long> saves = new ArrayList<>();
        ArrayList<Long> loads = new ArrayList<>();
        String[] nds = {"wash"};
        for (String name : nds) {
            Device device = new Device(name, gEngine);
            try {
                Scanner in = new Scanner(new File("i2/" + name + "apnotcomp"));
                while (in.hasNextLine()) {
                    String line = in.nextLine();
                    String[] tokens = line.split(" ");
                    String pn = tokens[3].split("\\.")[0];
                    if (device.getPort(pn) == null) {
                        device.addPort(pn);
                    }
                    long ip = Long.parseLong(tokens[1]);
                    Rule rule = new Rule(device, ip, Integer.parseInt(tokens[2]), device.getPort(pn));
                    rule.setHit(device.bddEngine.encodeIpv4(BigInteger.valueOf(ip), Integer.parseInt(tokens[2])));
                    HashSet<Change> changes = device.identifyChangesInsert(rule);
                    
                    ArrayList<ByteArrayOutputStream> boss = new ArrayList<>();
                    long start = System.nanoTime();
                    for (Change change : changes) {
                        int hit = change.getHit();
                        ByteArrayOutputStream bos = new ByteArrayOutputStream();
                        try {
                            BDDIO.save(device.bddEngine.bdd, hit, bos);
                            boss.add(bos);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    saves.add(System.nanoTime() - start);
                    start = System.nanoTime();
                    for (ByteArrayOutputStream bos : boss) {
                        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
                        BDDIO.load(gEngine.bdd, bis);
                    }
                    loads.add(System.nanoTime() - start);
                }
                
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
        BufferedWriter writer = new BufferedWriter(new FileWriter("result"));
        for (int i = 0; i < saves.size(); i++) {
            System.out.println(saves.get(i));
            System.out.println(loads.get(i));
            writer.write(saves.get(i).toString());
            writer.write("\n");
            writer.write(loads.get(i).toString());
            writer.write("\n");
        }
        writer.close();
    }
}
